package com.hzm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.wxpay.sdk.WXPayUtil;
import com.hzm.dao.CourseDao;
import com.hzm.dao.MemberDao;
import com.hzm.dao.OrderDao;
import com.hzm.dao.PayLogDao;

import com.hzm.entity.Course;
import com.hzm.entity.Member;
import com.hzm.entity.Order;
import com.hzm.entity.PayLog;
import com.hzm.service.PayLogService;
import com.hzm.service.PayService;
import com.hzm.utils.HttpClient;
import com.hzm.utils.Result;
import com.hzm.utils.WeixinConfig;
import com.hzm.vo.CourseDetailsVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @program: qy137-java
 * @description:
 * @author: 皇子明
 * @create: 2021-10-24 21:59
 **/
@Service
public class PayServiceImpl implements PayService {
    @Resource
    private OrderDao orderDao;
    @Resource
    private PayLogService payLogService;
    @Resource
    private CourseDao courseDao;
    @Resource
    private PayLogDao payLogDao;
    @Resource
    private MemberDao memberDao;
    @Override
    public Result createWeiXin(String id, String HuiYuanId) {
        CourseDetailsVo courseDetailsVo = courseDao.queryAllCourseAndTeacherName(id);
        Order order = new Order();

        if (courseDetailsVo != null) {
            //            根据订单号和课程id查询当前的订单是否已经存在
            QueryWrapper<Order> orderWrapper = new QueryWrapper<>();
            orderWrapper.eq("course_id",id);
            orderWrapper.eq("member_id",HuiYuanId);
            Order order1 = orderDao.selectOne(orderWrapper);
            if (order1==null){
                Member member = memberDao.selectById(HuiYuanId);
//            System.out.println(member);
//          订单主键
                String ID = UUID.randomUUID().toString().replace("-", "").substring(0, 19);
                order.setId(ID);
//          订单号
                String orderNo = UUID.randomUUID().toString().replace("-", "").substring(0, 19);
                order.setOrderNo(orderNo);
//            课程id
                order.setCourseId(courseDetailsVo.getId());
//           课程名称
                order.setCourseTitle(courseDetailsVo.getTitle());
//            课程封面
                order.setCourseCover(courseDetailsVo.getCover());
//            教师名称
                order.setTeacherName(courseDetailsVo.getName());
//            会员id
                order.setMemberId(HuiYuanId);
//            会员名称
                order.setNickname(member.getNickname());
//            手机号
                order.setMobile(member.getMobile());
//            订单费用
                order.setTotalFee(new BigDecimal("0.01"));
//            支付类型(微信支付)
                order.setPayType(0);
//           订单状态(未支付)
                order.setStatus(0);
//            是否删除
                order.setIsDeleted(false);
//            创建时间
                order.setGmtCreate(new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss").format(new Date()));
//            更新时间
                order.setGmtModified(new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss").format(new Date()));
                int insert = orderDao.insert(order);


                PayLog payLog=new PayLog();
                String playNo = UUID.randomUUID().toString().replace("-", "").substring(0, 19);
                payLog.setId(playNo);
                payLog.setOrderNo(orderNo);
                payLog.setPayTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                payLog.setTotalFee(null);
                payLog.setTransactionId(null);
                payLog.setTradeState("ERROR");
                payLog.setAttr(null);
                payLog.setPayType(0);
                payLog.setIsDeleted(false);
                payLog.setGmtCreate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                payLog.setGmtModified(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                payLogService.save(payLog);
                if (insert > 0) {
//                封装数据请求微信地址的参数
                    try {
                        Map<String, String> map = new HashMap<>();
//                wx8087d8149331d27c
                        map.put("appid", WeixinConfig.APPID);
                        map.put("mch_id", WeixinConfig.MCH_ID);
                        map.put("nonce_str", WXPayUtil.generateNonceStr()); //
                        map.put("body", courseDetailsVo.getTitle()); //课程标题
                        map.put("out_trade_no", orderNo);
                        map.put("total_fee", new BigDecimal("0.01").multiply(new BigDecimal("100")).longValue() + "");
                        map.put("spbill_create_ip", "192.168.31.243"); //部署服务器的地址。
                        //设置的回调的路径
                        map.put("notify_url", "http://192.168.31.243:9000/notifyWeiXinPay");//
//                    map.put("notify_url", "http://192.168.31.243:9000/#/DetailId");//
                        //支付类型   native 扫码支付
                        map.put("trade_type", "NATIVE");
                        //3.发送请求到微信的地址https://api.mch.weixin.qq.com/pay/unifiedorder
                        //httpclient:模拟浏览器发送请求。 get  post  (1)引入httpclient的依赖
                        HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
                        httpClient.setXmlParam(WXPayUtil.generateSignedXml(map, WeixinConfig.API_KEY)); //因为微信接口需要参数的格式必须xml格式
                        httpClient.setHttps(true);//是否支持https协议
                        httpClient.post();//发送请求 回车键
                        //4.得到微信响应的结果。
                        String content = httpClient.getContent();//得到结果
                        Map<String, String> resultMap = WXPayUtil.xmlToMap(content); //把xml格式的字符串转化为map对象

                        Order queryOrder = orderDao.selectById(ID);

                        if (resultMap.get("result_code").equals("SUCCESS")) {
//                        更改状态
                            Map map1 = new HashMap<>();
                            map1.put("out_trade_no", orderNo);//订单号
                            map1.put("course_id", id);
                            map1.put("total_fee", 0.01); //
                            map1.put("result_code", resultMap.get("result_code"));
                            map1.put("code_url", resultMap.get("code_url")); //二维码的地址
                            return new Result(2000, "生成微信支付二维码成功", map1);
                        } else {
                            return new Result(5000, "生成微信支付二维码已支付", null);
                        }

                    } catch (Exception e) {
                        return new Result(5000,"生成微信支付二维码失败",null);
                    }
                }

            }else{
                String orderNo = order1.getOrderNo();

//                封装数据请求微信地址的参数
                try {
                    Map<String, String> map = new HashMap<>();
//                wx8087d8149331d27c
                    map.put("appid", WeixinConfig.APPID);
                    map.put("mch_id", WeixinConfig.MCH_ID);
                    map.put("nonce_str", WXPayUtil.generateNonceStr()); //
                    map.put("body", courseDetailsVo.getTitle()); //课程标题
                    map.put("out_trade_no", orderNo);
                    map.put("total_fee", new BigDecimal("0.01").multiply(new BigDecimal("100")).longValue() + "");
                    map.put("spbill_create_ip", "192.168.31.243"); //部署服务器的地址。
                    //设置的回调的路径
                    map.put("notify_url", "http://192.168.31.243:9000/notifyWeiXinPay");//
//                    map.put("notify_url", "http://192.168.31.243:9000/#/DetailId");//
                    //支付类型   native 扫码支付
                    map.put("trade_type", "NATIVE");
                    //3.发送请求到微信的地址https://api.mch.weixin.qq.com/pay/unifiedorder
                    //httpclient:模拟浏览器发送请求。 get  post  (1)引入httpclient的依赖
                    HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
                    httpClient.setXmlParam(WXPayUtil.generateSignedXml(map, WeixinConfig.API_KEY)); //因为微信接口需要参数的格式必须xml格式
                    httpClient.setHttps(true);//是否支持https协议
                    httpClient.post();//发送请求 回车键
                    //4.得到微信响应的结果。
                    String content = httpClient.getContent();//得到结果
                    Map<String, String> resultMap = WXPayUtil.xmlToMap(content); //把xml格式的字符串转化为map对象

                    if (resultMap.get("result_code").equals("SUCCESS")) {
//                        更改状态
                        Map map1 = new HashMap<>();
                        map1.put("out_trade_no", orderNo);//订单号
                        map1.put("course_id", id);
                        map1.put("total_fee", 0.01); //
                        map1.put("result_code", resultMap.get("result_code"));
                        map1.put("code_url", resultMap.get("code_url")); //二维码的地址
                        return new Result(2000, "生成微信支付二维码成功", map1);
                    } else {
                        return new Result(5000, "生成微信支付二维码已支付", null);
                    }

                } catch (Exception e) {
                    return new Result(5000,"生成微信支付二维码失败",null);
                }

            }


        }
        return null;
    }

    @Override
    public Result getStatus(String orderNo) {
        Map<String, String> payStatus = getPayStatus(orderNo);
        PayLog payLog=new PayLog();
        if(payStatus==null){
            //支付失败


            return new Result(5000,"支付失败",null);
        }else if(StringUtils.equals(payStatus.get("trade_state"),"SUCCESS")){//2.已支付
            //2.1 添加支付记录t_pay_log

            QueryWrapper<PayLog> payLogWrapper = new QueryWrapper<>();
            payLogWrapper.eq("order_no",orderNo);

            payLog.setTotalFee(new BigDecimal(payStatus.get("total_fee")));
            payLog.setTransactionId(payStatus.get("transaction_id"));
            payLog.setTradeState("SUCCESS");
            payLog.setGmtCreate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            payLog.setGmtModified(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            payLogService.update(payLog,payLogWrapper);
            //2.2 修改订单的状态 未支付--->已支付
            updatePayStatus(orderNo,1);
//            查询当前的订单
            QueryWrapper<Order> wrapper = new QueryWrapper<>();
            wrapper.eq("order_no",orderNo);
            Order order = orderDao.selectOne(wrapper);
//            根据课程id查询课程消息,更改课程数量
            CourseDetailsVo queryCourse = courseDao.queryAllCourseAndTeacherName(order.getCourseId());
//            System.out.println("课程id"+queryCourse.getId());
//            进行更改
            Course course = new Course();
            Long buyCount = queryCourse.getBuyCount()+1;
            course.setBuyCount(buyCount);
            course.setId(order.getCourseId());
            int i = courseDao.updateById(course);



            return new Result(2000,"支付成功",payStatus);
        }else{
            //3.正在支付中
            return new Result(3000,"支付中",null);
        }
    }

    @Override
    public void updatePayStatus(String orderNo, int i) {
        Order order=new Order();
        order.setStatus(i);
        order.setGmtModified(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

        QueryWrapper<Order> wrapper=new QueryWrapper<>();
        wrapper.eq("order_no",orderNo);
        orderDao.update(order,wrapper);
    }

    public Map<String, String> getPayStatus(String orderNo) {
        try {
            //https://api.mch.weixin.qq.com/pay/orderquery
            String url = "https://api.mch.weixin.qq.com/pay/orderquery";
            //封装请求的参数
            Map<String, String> map = new HashMap<>();
            map.put("appid",WeixinConfig.APPID);
            map.put("mch_id", WeixinConfig.MCH_ID);
            map.put("out_trade_no", orderNo);
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            //模拟浏览器发送请求
            HttpClient httpClient = new HttpClient(url);
            httpClient.setXmlParam(WXPayUtil.generateSignedXml(map,WeixinConfig.API_KEY));//"Cc158380629071583806290715838062"));//"T6m9iK73b0kn9g5v426MKfHQH7X8rKwb"));
            httpClient.setHttps(true);
            httpClient.post();
            //得到响应的结果
            String xml = httpClient.getContent();
            Map<String,String> resultMap=WXPayUtil.xmlToMap(xml);
            return resultMap;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}
